﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ATM_Pro.Log;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Timers;
using ATM_Pro.Module;

namespace ATM_Pro
{
    public class GetTransPacket : ISendTrade
    {
        public GetTransPacket()
        {
            sph = new StatePacketHandle();
            wph = new WarnPacketHandle();
            tph = new TransPacketHandle();
            lph = new LivePacketHandle();
            boph = new BlockingOutPacketHandle();

            handlers = new IPacketHandler[] { wph, tph, lph, sph, boph };
        }
        private IPacketHandler[] handlers;
        private TcpClient client = null;
        private NetworkStream ns;
        private List<byte> lbuf;

        public WarnPacketHandle wph;//报警信息包
        public TransPacketHandle tph;//交易信息包
        public LivePacketHandle lph;//实时数据包
        public StatePacketHandle sph;//状态包
        public BlockingOutPacketHandle boph;//遮挡报警包

        public event ImageDataChangeHandle ConnectionServerHandle;

        public string AtmAddress { get; set; }
        public string IP { get; set; }
        public int Port { get; set; }

        //ImageHandle类中定义的枚举
        //0x01 --> 报警信息数据包
        //0x03 --> 交易信息数据包
        //0x04 --> 实时图像数据包
        //摄像机编号（水平=0x00/垂直=0x01/全景=0x02）

        public void InitSocket(object obj)
        {
            lbuf = new List<byte>();
            try
            {
                if (ns != null)
                {
                    ns.Close();
                    client.Close();
                }
                System.Threading.Thread.Sleep(1000);
                client = new TcpClient();
                client.Connect(this.IP, this.Port);
                ns = client.GetStream();
                Timer time = new Timer();
                time.Elapsed += new ElapsedEventHandler(timer_Elapsed);
                time.Interval = 10000;
                time.Enabled = true;
                ConnetSever(this, new DataChangeEventArgs("true", this.AtmAddress, this.IP));
            }
            catch (SocketException ex)
            {
                ConnetSever(this, new DataChangeEventArgs("false", this.AtmAddress, this.IP));
            }

        }

        protected void ConnetSever(object sender, DataChangeEventArgs e)
        {
            if (ConnectionServerHandle != null)
            {
                ConnectionServerHandle(sender, e);
            }
        }

        //分析数据
        protected void AnalysisData(byte[] byteBuf)
        {
            foreach (var handler in this.handlers)
            {
                if (handler.CanHandle(byteBuf))
                {
                    handler.Handle(byteBuf);
                }
            }
        }

        private void timer_Elapsed(object source, ElapsedEventArgs args)
        {
            SendHbTrade();
        }

        //发送报警回应包
        public void SendWarnPackBack(WarnPacketBean wb, int value)
        {
            byte[] packtype = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(2));
            byte[] warnId = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(wb.WarnId));
            byte camId = Convert.ToByte(wb.AtmBean.Cam.ID);
            byte isBackGroud = Convert.ToByte(value);
            byte[] length = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(packtype.Length + warnId.Length + 2));
            byte[] byteHb = new byte[] { 0xaa, 0x55, 0xaa, 0x55,
                            length[0],length[1],length[2],length[3],
                            packtype[0],packtype[1],packtype[2],packtype[3],
                            warnId[0],warnId[1],warnId[2],warnId[3],
                            camId,isBackGroud};
            try
            {
                if (ns != null)
                {
                    ns.Write(byteHb, 0, byteHb.Length);
                    ns.Flush();
                }

            }
            catch (IOException ex)
            {
                //System.Diagnostics.Debug.WriteLine("连接已经断开！");
                return;
            }
            catch (ObjectDisposedException ode)
            {
                //System.Diagnostics.Debug.WriteLine("对象释放异常！");
                return;
            }
        }

        //检测摄像机状态
        public void SendCheckCameraStatePacket()
        {
            byte[] length = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(5));
            byte[] packtype = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(6));
            byte atmId = Convert.ToByte(Enum.Parse(typeof(AtmAddress), this.AtmAddress));
            byte[] byteHb = new byte[] { 0xaa, 0x55, 0xaa, 0x55, 
                length[0], length[1], length[2], length[3], 
                packtype[0],packtype[1],packtype[2],packtype[3] ,
                atmId};
            try
            {
                if (ns != null)
                    ns.Write(byteHb, 0, byteHb.Length);
            }
            catch (IOException ex)
            {
                //System.Diagnostics.Debug.WriteLine("连接已经断开！");
                return;
            }
            catch (ObjectDisposedException ode)
            {
                //System.Diagnostics.Debug.WriteLine("对象释放异常！");
                return;
            }
        }

        //时间校验
        public void SendCheckSeverTimePacket()
        {
            if (string.IsNullOrEmpty(this.AtmAddress))
                return;
            byte[] length = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(8));
            byte[] packtype = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(7));
            byte atmId = Convert.ToByte(Enum.Parse(typeof(AtmAddress), this.AtmAddress));
            DateTime oldTime = new DateTime(1970, 1, 1, 0, 0, 0);
            DateTime nowTime = DateTime.Now;
            TimeSpan sp = new TimeSpan();
            sp = oldTime - nowTime;
            byte[] time = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(sp.Days * 24 * 60 * 60));
            byte[] byteHb = new byte[] { 0xaa, 0x55, 0xaa, 0x55, 
                length[0], length[1], length[2], length[3], 
                packtype[0],packtype[1],packtype[2],packtype[3] ,
                atmId};
            try
            {
                if (ns != null)
                    ns.Write(byteHb, 0, byteHb.Length);
            }
            catch (IOException ex)
            {
                //System.Diagnostics.Debug.WriteLine("连接已经断开！");
                return;
            }
            catch (ObjectDisposedException ode)
            {
                //System.Diagnostics.Debug.WriteLine("对象释放异常！");
                return;
            }
        }

        //设置人员不在时报警时间间隔
        public void SendWarnTimePacket(int second)
        {
            byte[] length = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(8));
            byte[] packtype = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(8));
            byte[] seconds = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(second));
            byte[] byteHb = new byte[] { 0xaa, 0x55, 0xaa, 0x55, 
                length[0], length[1], length[2], length[3], 
                packtype[0],packtype[1],packtype[2],packtype[3] ,
                seconds[0],seconds[1],seconds[2],seconds[3]};
            try
            {
                if (ns != null)
                    ns.Write(byteHb, 0, byteHb.Length);
            }
            catch (IOException ex)
            {
                //System.Diagnostics.Debug.WriteLine("连接已经断开！");
                return;
            }
            catch (ObjectDisposedException ode)
            {
                //System.Diagnostics.Debug.WriteLine("对象释放异常！");
                return;
            }
        }

        //发送心跳信号
        public void SendHbTrade()
        {
            byte[] bytes = BitConverter.GetBytes(0xaaaaaaaa);
            byte[] bytet = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(16));
            byte[] byteHb = new byte[24] {0xaa, 0x55, 0xaa, 0x55,
                bytet[0], bytet[1], bytet[2], bytet[3],
                bytes[0], bytes[1], bytes[2], bytes[3],
                bytes[0], bytes[1], bytes[2], bytes[3], 
                bytes[0], bytes[1], bytes[2], bytes[3] ,
            bytes[0], bytes[1], bytes[2], bytes[3] };

            try
            {
                if (ns != null)
                    ns.Write(byteHb, 0, byteHb.Length);
            }
            catch (IOException ex)
            {
                //System.Diagnostics.Debug.WriteLine("连接已经断开！");
                return;
            }
            catch (ObjectDisposedException ode)
            {
                //System.Diagnostics.Debug.WriteLine("对象释放异常！");
                return;
            }
        }

        //判断是不是包头
        bool IsHeader(byte[] hdr)
        {
            int i = 0;
            if (hdr[i++] == 0xaa && hdr[i++] == 0x55 && hdr[i++] == 0xaa && hdr[i++] == 0x55)
            {
                return true;
            }

            return false;
        }

        //打印接收的数据
        private static void PrintBytes(byte[] data)
        {
            Array.ForEach(data, b => System.Diagnostics.Debug.Write(b.ToString("x2")));
            System.Diagnostics.Debug.WriteLine("");
        }

        private static void LogBuffer(StreamWriter sw, byte[] pack, bool appendNewLine)
        {
            sw.Write(System.Text.ASCIIEncoding.ASCII.GetString(pack));
            if (appendNewLine)
            {
                sw.Write(sw.NewLine);
            }
            sw.Flush();
        }

        //接收数据
        public void GetData()
        {
            int count = 0;
            //int frameCount = 0;
            byte[] hdr = new byte[8];
            //StreamWriter sw = new StreamWriter(File.OpenWrite("log.txt"));
            try
            {
                while ((count = ns.Read(hdr, 0, hdr.Length)) == hdr.Length)
                {
                    if (IsHeader(hdr))
                    {
                        int n = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(hdr, 4));
                        int packetLen = n;

                        byte[] pack = new byte[packetLen + hdr.Length];

                        int byteRead = 0;

                        do
                        {
                            byteRead += ns.Read(pack, 0 + hdr.Length + byteRead, pack.Length - hdr.Length - byteRead);
                        } while (byteRead != n);

                        if (byteRead == packetLen)
                        {
                            hdr.CopyTo(pack, 0);
                            AnalysisData(pack);
                        }

                        //PrintBytes(hdr);
                        //LogBuffer(sw, pack, true);
                        //System.Diagnostics.Debug.WriteLine(++frameCount + " len: " + n.ToString());
                    }
                    //else
                    //{
                    //    PrintBytes(hdr);
                    //    //LogBuffer(sw, hdr, false);
                    //}
                }
            }
            catch (System.IO.IOException ex)
            {
                //System.Diagnostics.Debug.WriteLine("连接已经断开！");
                ConnetSever(this, new DataChangeEventArgs("false", this.AtmAddress, this.IP));
                return;
            }
            catch (ObjectDisposedException ode)
            {
                ConnetSever(this, new DataChangeEventArgs("false", this.AtmAddress, this.IP));
                return;
            }
            ConnetSever(this, new DataChangeEventArgs("false", this.AtmAddress, this.IP));
        }
    }
}

